#include "myselfwidget.h"
#include "ui_myselfwidget.h"
#include "util.h"
#include "videobox.h"
#include "vidhub.h"
#include "toast.h"
#include "confirmdialog.h"

#include <QFileDialog>
#include <modifymyselfdialog.h>
#include <QScrollBar>

////////////////////////////////// AttentionButton类 //////////////////////////////////
AttentionButton::AttentionButton(QWidget *parent)
    : QPushButton(parent)
{
    changeStatus(false);
}

bool AttentionButton::isAttention() const
{
    return isAttentionStatus;
}

void AttentionButton::changeStatus(bool isAttentioned)
{
    // 根据被关注的状态，调整按钮的样式
    this->isAttentionStatus = isAttentioned;
    if(isAttentioned){
        this->setText("已关注");
        this->setStyleSheet("QPushButton{"
                            "background-color : transparent;"
                            "color : #3ECEFE;"
                            "border-radius : 4px;"
                            "border : 1px solid #3ECEFE;"
                            "padding-left : 13px;"
                            "padding-right : 14px;"
                            "}");
        // 设置按钮上的图标
        this->setIconSize(QSize(24, 24));
        this->setIcon(QIcon(":/images/myself/guanzhu.png"));
    }else{
        this->setText("关注");
        this->setStyleSheet("QPushButton{"
                            "background-color : #3ECEFE;"
                            "color : #FFFFFF;"
                            "border-radius : 4px;"
                            "border : none;"
                            "}");
        // 取消图标
        this->setIcon(QIcon());
    }
}


MyselfWidget::MyselfWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MyselfWidget)
{
    ui->setupUi(this);

    initUI();

    connectSignalAndSlots();
}

MyselfWidget::~MyselfWidget()
{
    delete ui;
}

void MyselfWidget::initUI()
{
#ifdef TEST_UI
    // 往视频显示区域添加VideoBox-测试
    int resourceId = 10000;
    for(int i = 0; i < 20; ++i){
        model::VideoInfo videoInfo;
        resourceId++;
        videoInfo.userAvatarId = "";
        videoInfo.photoFileId = QString::number(resourceId++);
        videoInfo.videoFileId = QString::number(resourceId++);
        videoInfo.nickName = "用户昵称";
        videoInfo.likeCount = 1234;
        videoInfo.playCount = 23456;
        videoInfo.videoTitle = "【北京旅游攻略】一条视频告诉你去了北京该怎么玩";
        videoInfo.videoDuration = 10;
        videoInfo.videoUpTime = "9-16 12:28:58";
        VideoBox* videoBox =  new VideoBox(videoInfo);
        ui->layout->addWidget(videoBox, i/4, i%4);
    }
#endif

    ui->attentionBtn->hide();
    login = new Login();
}


void MyselfWidget::onAvatarBtnClicked()
{
    // 0. 注意：临时用户不能通过点击按钮修改用户头像
    auto dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getMyselfInfo()->isTempUser()){
        Toast::showMessage("请先登陆，登录成功之后才能修改头像", login);
        return;
    }

    // 1. 弹出对话框, 选择文件
    QString fileName = QFileDialog::getOpenFileName(nullptr, "选择头像", "", "Image Files (*.jpg *.png)");
    if(fileName.isEmpty())
    {
        LOG() << "取消选择头像";
        return ;
    }

    // 2. 读取文件内容
    QByteArray fileData = loadFileToByteArray(fileName);
    if(fileData.isEmpty()){
        LOG() << "头像文件读取失败";
        return ;
    }

    //3. 生成头像
    // ui->avatarBtn->setIcon(makeCirclesIcon(fileData, ui->avatarBtn->width() / 2));

    //4. 上传到服务器
    dataCenter->uploadPhotoAsync(fileData, ui->avatarBtn);
}

void MyselfWidget::onSettingBtnClicked()
{
    ModifyMyselfDialog* dialog = new ModifyMyselfDialog();
    dialog->exec();
    delete dialog;
}

void MyselfWidget::onUploadVideoBtn()
{
    //1. 打开选择文件对话框, 选择文件
    QString videoFilePath = QFileDialog::getOpenFileName(nullptr, "上传视频", "", "Videos (*.mp4 *.rmvb *.avi *.mov)");
    if(videoFilePath.isEmpty()) {
        LOG() << "取消上传视频";
        return ;
    }

    //2. 视频大小限制 上限为4G
    QFileInfo fileInfo(videoFilePath);
    int64_t fileSize = fileInfo.size();
    if(fileSize > (int64_t)4 * 1024 * 1024 * 1024) {
        LOG() << "视频文件必须小于4G";
        return ;
    }

    //3. 发送上传视频请求
    auto dataCenter = model::DataCenter::getInstance();
    dataCenter->uploadVideoAsync(videoFilePath);

    //4. 切换到上传视频界面
    emit switchUploadVideoPage(UploadPage, videoFilePath);
}

void MyselfWidget::connectSignalAndSlots()
{
    // 头像按钮绑定槽函数
    connect(ui->avatarBtn, &AvatarButton::clicked, this, &MyselfWidget::onAvatarBtnClicked);
    // 修改按钮绑定槽函数
    connect(ui->settingBtn, &AvatarButton::clicked, this, &MyselfWidget::onSettingBtnClicked);
    // 上传视频按钮绑定槽函数
    connect(ui->uploadVideoBtn, &AvatarButton::clicked, this, &MyselfWidget::onUploadVideoBtn);
    // QScrollArea垂直滚动条滑动
    connect(ui->scrollArea->verticalScrollBar(), &QScrollBar::valueChanged, this, &MyselfWidget::onScrollAreaValueChanged);
    // 点击关注按钮
    connect(ui->attentionBtn, &QPushButton::clicked, this, &MyselfWidget::onAttentionBtnClicked);
    // 昵称按钮点击信号槽绑定
    connect(ui->nicknameBtn, &QPushButton::clicked, this, &MyselfWidget::onNicknameBtnClicked);
    // 退出登录按钮信号槽绑定
    connect(ui->quitBtn, &QPushButton::clicked, this, &MyselfWidget::onQuitBtnClicked);

    auto dataCenter = model::DataCenter::getInstance();
    // 获取当前⽤⼾信息成功
    connect(dataCenter, &model::DataCenter::getMyselfInfoDone, this, &MyselfWidget::getMyselfInfoDone);
    // 获取其他用户信息成功
    connect(dataCenter, &model::DataCenter::getOtherUserInfoDone, this, &MyselfWidget::getOtherUserInfoDone);
    // 获取用户头像成功
    connect(dataCenter, &model::DataCenter::downloadPhotoDone, this, &MyselfWidget::getAvatarDone);
    // 设置用户头像成功
    connect(dataCenter, &model::DataCenter::uploadPhotoDone, this, &MyselfWidget::uploadAvatarDone1);
    // 修改用户信息中的头像id成功
    connect(dataCenter, &model::DataCenter::setAvatarDone, this, &MyselfWidget::uploadAvatarDone2);
    // 获取用户视频列表成功
    connect(dataCenter, &model::DataCenter::getUserVideoListDone, this, &MyselfWidget::getUserVideoListDone);
    // 删除视频成功
    connect(dataCenter, &model::DataCenter::deleteVideoDone, this, &MyselfWidget::deleteVideoDone);
    // 关注用户
    connect(dataCenter, &model::DataCenter::newAttentionDone, this, &MyselfWidget::newAttentionDone);
    // 取消关注用户
    connect(dataCenter, &model::DataCenter::delAttentionDone, this, &MyselfWidget::delAttentionDone);
    // 退出登录成功
    connect(dataCenter, &model::DataCenter::logoutDone, this, &MyselfWidget::logoutDone);

    // 短信登录成功
    connect(login, &Login::loginSuccess, this, [=]{
        //dataCenter->getMyselfInfoAsync();
        // 清空datacenter中保存的临时用户信息，从新加载当前用户的个人信息
        dataCenter->clearUserInfo();
        loadMyself();
    });

    // 修改密码成功
    connect(dataCenter, &model::DataCenter::setPasswordDone, this, [=]{
        LOG()<<"修改密码成功";
    });

    // 修改昵称成功
    connect(dataCenter, &model::DataCenter::setNicknameDone, this, &MyselfWidget::setNicknameDone);

}

void MyselfWidget::hideWidget(bool isHide)
{
    // 临时⽤⼾需要隐藏界⾯上控件，⾮临时⽤⼾显⽰控件
    if(isHide) {
        ui->attentionBtn->hide();
        ui->attentionCountLabel->hide();
        ui->attentionLabel->hide();
        ui->fansLabel->hide();
        ui->fansCountLabel->hide();
        ui->likeLabel->hide();
        ui->likeCountLabel->hide();
        ui->playLabel->hide();
        ui->playCountLabel->hide();
        ui->settingBtn->hide();
        ui->quitBtn->hide();
        ui->uploadVideoBtn->hide();
        // scrollArea隐藏后，控件的位置仍旧保留
        QSizePolicy sizePolicy = ui->scrollArea->sizePolicy();
        sizePolicy.setRetainSizeWhenHidden(true);
        ui->scrollArea->setSizePolicy(sizePolicy);
        ui->scrollArea->hide();
        sizePolicy = ui->titleBar->sizePolicy();
        sizePolicy.setRetainSizeWhenHidden(true);
        ui->titleBar->setSizePolicy(sizePolicy);
        ui->titleBar->hide();
    } else {
        ui->attentionBtn->show();
        ui->attentionCountLabel->show();
        ui->attentionLabel->show();
        ui->fansLabel->show();
        ui->fansCountLabel->show();
        ui->likeLabel->show();
        ui->likeCountLabel->show();
        ui->playLabel->show();
        ui->playCountLabel->show();
        ui->settingBtn->show();
        ui->quitBtn->show();
        ui->uploadVideoBtn->show();
        ui->scrollArea->show();
        ui->titleBar->show();
    }
}

void MyselfWidget::clearVideoList()
{
    QLayoutItem* videoBoxWidget = nullptr;
    while(nullptr != (videoBoxWidget = ui->layout->takeAt(0))){
        delete videoBoxWidget->widget();
        delete videoBoxWidget;
    }
}

void MyselfWidget::loadMyself()
{
    // 加载个⼈信息
    getMyselfInfo();

    // 加载个⼈视频列表
    userId = "";
    getUserVideoList("", 1);

    // 切换到个⼈模式，即允许点击⽤⼾头像按钮修改个⼈头像
    ui->avatarBtn->changeMode(true);
    ui->avatarBtn->setEnabled(true);
}

void MyselfWidget::loadOtherUser(const QString &userId)
{
    // 加载其他用户的个人信息
    getOtherUserInfo(userId);

    // 加载其他用户的视频列表
    this->userId = userId;
    getUserVideoList(userId, 1);

    // 切换到其他用户模式
    ui->avatarBtn->changeMode(false);
    ui->avatarBtn->setEnabled(false);
}


void MyselfWidget::getMyselfInfo()
{
    auto dataCenter = model::DataCenter::getInstance();
    if(dataCenter->getMyselfInfo() == nullptr) {
        // 没有数据 请求数据
        dataCenter->getMyselfInfoAsync();
    } else {
        // 已经有数据了
        getMyselfInfoDone();
    }
}

void MyselfWidget::getMyselfInfoDone()
{
    // 获取用户数据
    auto dataCenter = model::DataCenter::getInstance();
    const auto& myself = dataCenter->getMyselfInfo();
    if(myself->isTempUser()) {
        // 如果是临时⽤⼾
        hideWidget(true);
        ui->avatarBtn->setIcon(QIcon(":/image/myself/defaultAvatar.png"));
        ui->nicknameBtn->setText("点击登录");
        ui->nicknameBtn->adjustSize();
        ui->nicknameBtn->setEnabled(true); // 允许点击昵称
        return ;
    } else if(myself->isBUser()) {
        // 管理员 显示系统按钮 管理员可以后台操作
        VidHub* bitPlayer = VidHub::getInstance();
        bitPlayer->showSystemPageBtn(true);
    }

    // 普通⽤⼾和管理员都要恢复界⾯控件
    hideWidget(false);

    // 2. 界⾯更新
    // 设置昵称，根据昵称宽度调整设置按钮距离
    ui->nicknameBtn->setText(myself->nickname);
    ui->nicknameBtn->adjustSize();
    ui->nicknameBtn->setEnabled(false);
    // 根据昵称按钮⽂本⻓度移动设置按钮，即让设置按钮紧跟在昵称按钮之后
    QRect rect = ui->nicknameBtn->geometry();
    ui->settingBtn->move(rect.x() + rect.width() + 8, ui->settingBtn->geometry().y());

    // 设置关注数、粉丝数、点赞数、播放数
    ui->attentionCountLabel->setText(intToString2(myself->followedCount));
    ui->fansCountLabel->setText(intToString2(myself->followerCount));
    ui->likeCountLabel->setText(intToString2(myself->likeCount));
    ui->playCountLabel->setText(intToString2(myself->playCount));

    // 3. 设置头像
    if(myself->avatarFileId.isEmpty()) {
        // 临时用户设置默认头像
        ui->avatarBtn->setIcon(QIcon(":/image/myself/defaultAvatar.png"));
    } else {
        dataCenter->downloadPhotoAsync(myself->avatarFileId);
    }

    // 4. 其他：隐藏关注按钮、不能点击登录、允许修改头像
    ui->attentionBtn->hide();
    ui->myVideoLabel->setText("我的视频");

}

void MyselfWidget::getOtherUserInfo(const QString &userId)
{
    // 给服务器发送获取其他用户信息的请求
    auto dataCenter = model::DataCenter::getInstance();
    dataCenter->getOtherUserInfoAsync(userId);
}

void MyselfWidget::getOtherUserInfoDone()
{
    // 1. 界面控件显示隐藏处理
    hideWidget(false);
    // 隐藏 设置用户信息按钮、退出登录按钮、上传视频按钮
    ui->settingBtn->hide();
    ui->quitBtn->hide();
    ui->uploadVideoBtn->hide();
    ui->avatarBtn->setEnabled(false);
    ui->nicknameBtn->setEnabled(false);

    // 2. 获取其他用户的个人信息
    auto dataCenter = model::DataCenter::getInstance();
    auto otherUserInfo = dataCenter->getOtherUserInfo();

    // 3. 更新界面数据
    // 设置昵称、关注数、粉丝数、点赞数、播放数
    ui->nicknameBtn->setText(otherUserInfo->nickname);
    ui->attentionCountLabel->setText(intToString2(otherUserInfo->followedCount));
    ui->fansCountLabel->setText(intToString2(otherUserInfo->followerCount));
    ui->likeCountLabel->setText(intToString2(otherUserInfo->likeCount));
    ui->playCountLabel->setText(intToString2(otherUserInfo->playCount));
    // 设置关注按钮状态
    // ui->attentionBtn->changeStatus(otherUserInfo->isFollowing == 1);
    ui->myVideoLabel->setText("TA的视频");

    // 4. 更新用户头像
    if(otherUserInfo->avatarFileId.isEmpty()){
        ui->avatarBtn->setIcon(QIcon(":/images/myself/defaultAvatar.png"));
    }else{
        dataCenter->downloadPhotoAsync(otherUserInfo->avatarFileId);
    }
}

void MyselfWidget::getAvatarDone(const QString &fileId, const QByteArray &data)
{
    auto dataCenter = model::DataCenter::getInstance();
    auto myself = dataCenter->getMyselfInfo();
    if(myself != nullptr && myself->avatarFileId == fileId) {
        ui->avatarBtn->setIcon(makeCirclesIcon(data, ui->avatarBtn->width() / 2));
    }
}

void MyselfWidget::uploadAvatarDone1(const QString &fileId, QWidget *whichPage)
{
    if(whichPage != ui->avatarBtn) {
        return ;
    }
    // 向服务器发送修改用户头像id的请求
    auto dataCenter = model::DataCenter::getInstance();
    dataCenter->setAvatarAsync(fileId);
}

void MyselfWidget::uploadAvatarDone2()
{
    // 向服务器发送获取用户新头像的请求
    auto dataCenter = model::DataCenter::getInstance();
    auto myself = dataCenter->getMyselfInfo();
    dataCenter->downloadPhotoAsync(myself->avatarFileId);
}

void MyselfWidget::getUserVideoList(const QString &userId, int pageIndex)
{
    auto dataCenter = model::DataCenter::getInstance();
    auto userVideoList = dataCenter->getUserVideoList();
    if(pageIndex == 1) {
        // 清空dataCenter中该用户视频数据
        userVideoList->clearVideoList();
        // 清空界面中的视频数据
        clearVideoList();
    }
    dataCenter->getUserVideoListAsync(userId, pageIndex, "myPage");
    // pageIndex+1，在获取下一页视频的时候就可以直接使用VideoList中的pageIndex
    userVideoList->setPageIndex(pageIndex+1);
}

void MyselfWidget::getUserVideoListDone(const QString &userId, const QString &whichPage)
{
    if("myPage" != whichPage){
        return;
    }
    auto dataCenter = model::DataCenter::getInstance();
    auto userVideoList = dataCenter->getUserVideoList();

    const int rowCount = 4;
    for(int i = ui->layout->count(); i < userVideoList->getVideoListCount(); ++i){
        int row = i / rowCount;
        int col = i % rowCount;

        VideoBox* videoBox = new VideoBox(userVideoList->videoInfos[i]);
        ui->layout->addWidget(videoBox, row, col);
        // 如果是当前登录用户获取自己的视频列表，删除更多按钮应该显示出来
        if(userId.isEmpty()) {
            videoBox->showMoreBtn(true);
            // 绑定删除信号
            connect(videoBox, &VideoBox::deleteVideo, this, &MyselfWidget::deleteVideo);
        }
    }

    repaint();
}

void MyselfWidget::onScrollAreaValueChanged(int value)
{
    if(value != ui->scrollArea->verticalScrollBar()->maximum()) {
        return ;
    }

    // 如果垂直滚动条滚动到底部的时候，需要获取下一页视频
    auto dataCenter = model::DataCenter::getInstance();
    auto userVideList = dataCenter->getUserVideoList();
    dataCenter->getUserVideoListAsync(userId, userVideList->getPageIndex(), "myPage");
    userVideList->setPageIndex(userVideList->getPageIndex()+1);
}

void MyselfWidget::deleteVideo(const QString &videoId)
{
    auto dataCenter = model::DataCenter::getInstance();
    dataCenter->deleteVideoAsync(videoId);
}

void MyselfWidget::deleteVideoDone(const QString &videoId)
{
    LOG()<<"删除视频成功，videoId = "<<videoId;
    this->getUserVideoList("", 1);
}

void MyselfWidget::onAttentionBtnClicked()
{
    // 注意：如果当前用户是临时用户，临时用户不能去关注其他用户
    auto dataCenter = model::DataCenter::getInstance();
    auto myselfInfo = dataCenter->getMyselfInfo();
    if(myselfInfo->isTempUser()){
        Toast::showMessage("请先登陆或注册", login);
        return;
    }

    bool isAttentioned = ui->attentionBtn->isAttention();
    isAttentioned = !isAttentioned;
    ui->attentionBtn->changeStatus(isAttentioned);

    // 通知服务器修该用户是否被关注信息
    auto otherUserInfo = dataCenter->getOtherUserInfo();
    if(otherUserInfo ==nullptr){
        Toast::showMessage("被关注的用户不存在，无法关注...");
        return;
    }

    if(isAttentioned) {
        dataCenter->newAttentionAsync(otherUserInfo->userId);
    } else {
        dataCenter->delAttentionAsync(otherUserInfo->userId);
    }
}

void MyselfWidget::newAttentionDone()
{
    auto dataCenter = model::DataCenter::getInstance();
    auto otherUserInfo = dataCenter->getOtherUserInfo();

    // 更新界面UI
    int64_t followerCount = otherUserInfo->followerCount + 1;
    ui->fansCountLabel->setText(intToString2(followerCount));

    // 更新DataCenter
    otherUserInfo->followerCount = followerCount;
}

void MyselfWidget::delAttentionDone()
{
    auto dataCenter = model::DataCenter::getInstance();
    auto otherUserInfo = dataCenter->getOtherUserInfo();

    // 更新界面UI
    int64_t followerCount = otherUserInfo->followerCount - 1;
    ui->fansCountLabel->setText(intToString2(followerCount));
    // 更新DataCenter
    otherUserInfo->followerCount = followerCount;
}

void MyselfWidget::onNicknameBtnClicked()
{
    // 如果当前用户是临时用户，显示登录窗口
    auto dataCenter = model::DataCenter::getInstance();
    auto myselfInfo = dataCenter->getMyselfInfo();
    if(myselfInfo->isTempUser()){
        // 登录之前先清除之前界面上流的旧数据
        // login->reset();
        login->show();
    }
}

void MyselfWidget::onQuitBtnClicked()
{
    // 显示确认或取消对话框
    ConfirmDialog confirmDlg;
    confirmDlg.setText("确认退出登录吗？");
    confirmDlg.exec();

    // 如果用户选择确定则退出
    if(confirmDlg.getConfirm()){
        login->reset();
        // 给服务器发送退出登录请求
        auto dataCenter = model::DataCenter::getInstance();
        // TODO
        dataCenter->logoutAsync();
    }
}

void MyselfWidget::logoutDone()
{
    // 清空界面上的数据 以及 DataCenter中的数据
    clearVideoList();
    auto dataCenter = model::DataCenter::getInstance();
    dataCenter->getVideoListPtr()->clearVideoList();

    // 将当前用户设置为临时用户
    dataCenter->buildTempUserInfo();
    loadMyself();

    // 注意：主界面上的系统页面切换按钮隐藏
    VidHub::getInstance()->showSystemPageBtn(false);
}

void MyselfWidget::setNicknameDone(const QString & nickName)
{
    // 修改我的页面中的昵称
    ui->nicknameBtn->setText(nickName);
    ui->nicknameBtn->adjustSize();
    QRect rect = ui->nicknameBtn->geometry();
    ui->settingBtn->move(rect.x() + rect.width() + 8, rect.y());

    // 修改DataCenter中保存的个人信息中的昵称
    auto dataCenter = model::DataCenter::getInstance();
    auto myselfInfo = dataCenter->getMyselfInfo();
    myselfInfo->nickname = nickName;
}


